﻿using System;

using System.Collections.Generic;
using System.Text;
using Silvermoon.Controls.Classes;
using Silvermoon.Controls.Interfaces;
using System.Drawing;
using Silvermoon.Controls.Base;
using Silvermoon.Visuals;
using Silvermoon.Images;

namespace Silvermoon.Controls
{
    /// <summary>
    /// Provides hierarchical Items in conjucton with <see cref="T:TreeView"/>.
    /// </summary>
    public class TreeViewItem : ListViewItem, IPage
    {
        #region fields

        private string title;
        private ButtonBase button;
        private ImageVisual arrowImage;
        private TreeListView itemListView;
        private Control control;
        private bool? hasItems;

        #endregion
        #region ctors

        public TreeViewItem()
            : base()
        {
        }

        #endregion
        #region props

        public TreeView TreeView
        {
            get
            {
                return (ListView as TreeListView).TreeView;
            }
        }

        internal TreeListView ItemListView
        {
            get
            {
                if (itemListView == null)
                {
                    itemListView = new TreeListView(TreeView, this);
                    Invalidate(InvalidationFlag.LayoutAppearance);
                }
                return itemListView;
            }
        }

        /// <summary>
        /// Gets the listview that holds or will hold the child items of this node.
        /// </summary>
        public ListViewBase NodesListView { get { return ItemListView; } }


        public TreeViewItem ParentItem { get; internal set; }

        /// <summary>
        /// Gets the list of child items to read or to populate.
        /// </summary>
        public IList<ItemBase> Items { get { return ItemListView.Items; } }

        /// <summary>
        /// Gets or sets whether the item has child items.
        /// If not set, the return value depends on the Items in <paramref name="Items"/>.
        /// </summary>
        public bool HasItems
        {
            get { if (hasItems.HasValue) return hasItems.Value; return itemListView != null && itemListView.ItemCount > 0; }
            //get { return true; }
            set { hasItems = value; }
        }

        public string Title { get { return title; } set { if (title != value) { OnTitleChanging(title, value); title = value; } } }

        public ButtonBase Button { get { return button; } set { if (button != value) { OnButtonChanging(button, value); button = value; ; } } }

        /// <summary>
        /// Gets or sets the control to show when the item is clicked.
        /// If not set, an autogenerated ListView is used to show the child Items, if Items has values, otherwise this value is null.
        /// </summary>
        public Control Control
        {
            get
            {
                if (control != null) return control;
                if (HasItems) return ItemListView;
                return null;
            }
            set { if (control != value) { control = value; OnControlChanged(); } }
        }

        #endregion
        #region methods

        protected override void OnLayout()
        {
            PrepareArrowImage();
            base.OnLayout();
        }

        protected virtual void OnButtonChanging(ButtonBase oldButton, ButtonBase newButton)
        {
            Invalidate(InvalidationFlag.Custom | InvalidationFlag.LayoutAppearance);
        }

        protected virtual void OnTitleChanging(string oldTitle, string newTitle)
        {
        }

        protected virtual void OnControlChanged()
        {
            Invalidate(InvalidationFlag.LayoutAppearance | InvalidationFlag.Custom);
        }

        public void BeginInit()
        {
            if (ItemListView != null) itemListView.BeginInit();
        }

        public void EndInit()
        {
            if (itemListView != null) itemListView.EndInit();
        }

        public override void OnClick()
        {
            base.OnClick();
            TreeView.Page = this;
        }

        /// <summary>
        /// Resets the treeview item and deletes all sub items and resources.
        /// </summary>
        public virtual void Reset()
        {
            Items.Clear();
        }

        private void PrepareArrowImage()
        {
            if (HasItems)
            {
                if (arrowImage == null)
                {
                    arrowImage = new ImageVisual();
                    arrowImage.Image = SysImages.SubItemArrow;
                    arrowImage.Size = new Size(12, 24);
                    arrowImage.Color = Color.Empty;
                    arrowImage.UseTextColor = true;
                }
                //if (!visuals.Contains(subMenuImage)) visuals.Insert(0, subMenuImage);
                arrowImage.Bounds = Control.ScaledRect(Width - 20 - arrowImage.Width, (Height - arrowImage.Height) / 2, arrowImage.Width, arrowImage.Height);
            }
            //else
            //{
            //     if (subMenuImage != null) visuals.Remove(subMenuImage);
            //}
        }

        private IEnumerable<Visual> GetBaseVisuals()
        {
            return base.Visuals;
        }

        public override IEnumerable<Visual> Visuals
        {
            get
            {
                foreach (Visual v in GetBaseVisuals()) yield return v;
                if (arrowImage != null) yield return arrowImage;
            }
            protected set
            {
                base.Visuals = value;
            }
        }


        #endregion
        #region IHeaderData Members
        IPage IPage.ParentPage
        {
            get
            {
                if (ParentItem != null) return ParentItem;
                TreeListView tlv = ListView as TreeListView;
                return tlv != null ? tlv.TreeView : null;
            }
        }

        #endregion

    }
}
